package com.xyzwps.mvckotlin.service

import com.xyzwps.mvckotlin.dao.model.Article
import com.xyzwps.mvckotlin.dao.repository.ArticleRepository
import org.springframework.stereotype.Service

import com.xyzwps.mvckotlin.assertTrue
import com.xyzwps.mvckotlin.exception.illegalParam
import org.slf4j.LoggerFactory

import org.apache.commons.lang3.StringUtils.isEmpty

@Service
class ArticleService(val markdownItService: MarkdownItService,
                     val articleRepository: ArticleRepository) {

    companion object {
        private val log = LoggerFactory.getLogger(ArticleService::class.java)
    }

    suspend fun getById(id: Long): Article? {
        log.info("try to get article by id {}.", id)
        val article = articleRepository.getById(id).await()
        log.info("article with id {} was {} found.", id, if (article == null) "not" else "")
        if (article == null) return null
        return if (isEmpty(article.renderedContent)) renderContent(article) else article
    }

    /**
     * @param id 如果为 `null`，就从最新的开始查；否则，查询此 id 之前的文章
     * @param size 一次查询多少个。要求值大于 0
     */
    suspend fun getSummaryBeforeId(id: Long?, size: Int): List<Article> {
        assertTrue(id == null || id > 0, illegalParam("id"))
        assertTrue(size > 0, illegalParam("size"))
        return articleRepository.getArticlesBeforeId(id, size).await()
    }

    suspend fun addNewArticle(title: String, content: String): Article {
        val newArticle = Article(title = title, content = content, renderedContent = markdownItService.render(content))
        return articleRepository.insert(newArticle).await()
    }
    suspend fun update(id: Long, title: String, content: String) {
        val article = Article(id = id, title = title, content = content, renderedContent = markdownItService.render(content))
        articleRepository.update(article)
    }

    /**
     * 这里总是假定 article 的 content 不是 null
     */
    private suspend fun renderContent(article: Article): Article {
        article.renderedContent = markdownItService.render(article.content ?: "")
        return articleRepository.update(article).await()
    }

}